package io.dcloud.uniplugin

import TCPClient

import android.os.Handler
import android.os.Looper
import android.util.Log
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject

import io.dcloud.feature.uniapp.annotation.UniJSMethod
import io.dcloud.feature.uniapp.bridge.UniJSCallback
import io.dcloud.feature.uniapp.common.UniDestroyableModule
import java.nio.charset.Charset
import java.util.Base64
import java.util.concurrent.ConcurrentHashMap

class TCPModule  : UniDestroyableModule()   {
    private val tcpClient = TCPClient()
    private val mainHandler = Handler(Looper.getMainLooper())
    private var currentDataType = 1 // 1=字符串, 2=十六进制, 3=Base64
    private var timeout = 10000 // 连接超时时间，单位毫秒
    private val UTF_8 = Charset.forName("UTF-8")
    private var isModuleActive = false // 模块激活状态
    // 新增：保存事件与回调的映射
    private val eventCallbacks = ConcurrentHashMap<String, UniJSCallback>()
    private val eventListeners = ConcurrentHashMap<String, Boolean>()
    // 模块激活
    @UniJSMethod(uiThread = true)
    fun activate() {
        isModuleActive = true
        Log.d("TCPPlugin", "模块已激活")
    }
    //run JS thread
    @UniJSMethod (uiThread = false)
    fun  testSyncFunc(): JSONObject {
        val data =JSONObject();
        data.put("code", "success");
        return data;
    }
    // 在TCPModule中添加
    @UniJSMethod(uiThread = true)
    fun triggerTestEvent(eventName: String, message: String) {
        Log.d("TCPPlugin", "强制触发测试事件: $eventName, 消息: $message")
        val data = JSONObject()
        data.put("testMessage", message)

        // 强制注册事件（仅用于测试）
        eventListeners[eventName] = true
        Log.d("TCPPlugin", "强制注册事件: $eventName")

        fireGlobalEventCallback(eventName, data)
    }
    @UniJSMethod(uiThread = false)
    fun connect(params: String) {
        if (!isModuleActive) {
            Log.e("TCPPlugin", "模块未激活，无法连接")
            fireErrorEvent(1005, "模块未激活")
            return
        }
        if (mWXSDKInstance == null) {
            Log.e("TCPPlugin", "上下文为空，无法连接")
            fireErrorEvent(1004, "插件上下文为空")
            return
        }

        try {
            val json = JSONObject.parseObject(params)
            val host = json.getString("host")
            val port = json.getIntValue("port")
            timeout = json.getIntValue("timeout").coerceAtLeast(1000)
            currentDataType = json.getIntValue("dataType")

            Log.d("TCPPlugin", "准备连接: $host:$port, 超时: $timeout ms, 类型: $currentDataType")

            // 清空旧监听，避免内存泄漏
            tcpClient.clearListeners()

            // 使用匿名内部类实现接口
            tcpClient.setStatusListener(object : TCPClient.OnStatusListener {
                override fun onStatus(isConnected: Boolean, error: String?) {
                    mainHandler.post {
                        if (!isModuleActive) return@post
                        Log.d("TCPPlugin", "连接状态: $isConnected, 错误: $error")
                        // 增加连接状态有效性检查
                        if (isConnected && tcpClient.isConnected()) {
                            val event = "connect"
                            fireGlobalEventCallback(event, null)
                            Log.d("TCPPlugin", "触发 connect 事件")
                        } else {
                            val event = "disconnect"
                            val data = JSONObject()
                            if (error != null) data.put("error", error)
                            fireGlobalEventCallback(event, data)
                            Log.d("TCPPlugin", "触发 disconnect 事件")
                        }
                    }
                }
            })

            // 同样修正 ByteArrayListener
            tcpClient.setByteArrayListener(object : TCPClient.OnByteArrayListener {
                override fun onByteArray(bytes: ByteArray?) {
                    mainHandler.post {
                        if (!isModuleActive || bytes == null) {
                            Log.e("TCPPlugin", "数据接收异常: 模块未激活或数据为空")
                            return@post
                        }

                        Log.d("TCPPlugin", "接收数据: ${bytes.size}字节")
                        when (currentDataType) {
                            1 -> {
                                val message = String(bytes, UTF_8)
                                val data: JSONObject = JSONObject()
                                data.put("message", message)
                                fireGlobalEventCallback("receiveString", data)
                            }
                            2 -> {
                                val hex = tcpClient.byteArrayToHexString(bytes)
                                val data =JSONObject()
                                    data.put("hex", hex)
                                fireGlobalEventCallback("receiveHex", data)
                            }
                            3 -> {
                                val base64 = Base64.getEncoder().encodeToString(bytes)
                                val data: JSONObject  =JSONObject();
                                data.put("data", base64)
                                data.put("length", bytes.size)
                                fireGlobalEventCallback("receiveBytes",data)
                            }
                        }
                    }
                }
            })

            tcpClient.connect(host, port, timeout)
        } catch (e: Exception) {
            Log.e("TCPPlugin", "连接异常", e)
            fireErrorEvent(1001, "连接失败: ${e.message}")
        }
    }

    // 发送数据
    @UniJSMethod(uiThread = false)
    fun send(params: String) {
        if (!isModuleActive || mWXSDKInstance == null) {
            Log.e("TCPPlugin", "模块未激活或上下文为空，无法发送")
            fireErrorEvent(1005, "模块未激活或上下文为空")
            return
        }

        try {
            val json = JSONObject.parseObject(params)
            val dataType = json.getIntValue("dataType")
            val data = json.getString("data")

            val bytes = when (dataType) {
                1 -> data.toByteArray(UTF_8)
                2 -> tcpClient.hexStringToByteArray(data)
                3 -> Base64.getDecoder().decode(data)
                else -> throw IllegalArgumentException("不支持的数据类型: $dataType")
            }

            tcpClient.sendData(bytes, object : TCPClient.OnSendListener {
                override fun onSendSuccess() {
                    mainHandler.post {
                        if (isModuleActive) {
                            Log.d("TCPPlugin", "发送成功")
                            fireGlobalEventCallback("sendSuccess", null)
                        }
                    }
                }

                override fun onSendFailed(error: String) {
                    mainHandler.post {
                        if (isModuleActive) {
                            Log.e("TCPPlugin", "发送失败: $error")
                            val data2  =JSONObject();
                                data2.put("error", error)
                            fireGlobalEventCallback("error",data2)
                        }
                    }
                }
            })
        } catch (e: Exception) {
            Log.e("TCPPlugin", "发送异常", e)
            fireErrorEvent(1002, "发送失败: ${e.message}")
        }
    }

    // 断开连接
    @UniJSMethod(uiThread = false)
    fun disconnect() {
        Log.d("TCPPlugin", "断开连接")
        tcpClient.disconnect()
    }

    // 触发全局事件
// 优化事件触发方法
    private fun fireGlobalEventCallback(eventName: String, data: JSONObject?) {
        if (!isModuleActive) {
            Log.e("TCPPlugin", "模块未激活，跳过事件: $eventName")
            return
        }

        if (!eventListeners.containsKey(eventName)) {
            Log.d("TCPPlugin", "未注册事件: $eventName")
            return
        }


        val finalData = data ?: JSONObject()
        Log.d("TCPPlugin", "触发事件: $eventName, 数据: ${finalData.toJSONString()}")

        // 确保在主线程触发事件
        if (Looper.myLooper() != Looper.getMainLooper()) {

            mainHandler.post { internalFireEvent(eventName, finalData) }
        } else {
            internalFireEvent(eventName, finalData)
        }
    }

    private fun internalFireEvent(eventName: String, data: JSONObject) {
        try {
            if (mWXSDKInstance != null) {
                // 转换为Map确保兼容性
                val dataMap = jsonObjectToMap(data)
                val callback = eventCallbacks[eventName] ?: return
                // 直接调用保存的回调函数
                callback.invoke(dataMap)
                mWXSDKInstance.fireGlobalEventCallback(eventName, dataMap)
            } else {
                Log.e("TCPPlugin", "上下文为空，事件发送失败")
            }
        } catch (e: Exception) {
            Log.e("TCPPlugin", "事件发送异常", e)
        }
    }


    private fun jsonObjectToMap(json: JSONObject): Map<String, Any> {
        val map = mutableMapOf<String, Any>()

        // 使用 Kotlin 的 entries 扩展属性（更简洁）
        for ((key, value) in json.entries) {
            when (value) {
                is JSONObject -> map[key] = jsonObjectToMap(value)
                is JSONArray -> map[key] = jsonArrayToList(value)
                else -> map[key] = value as Any // 处理 null 值
            }
        }

        return map
    }
    private fun jsonArrayToList(array: JSONArray): List<Any> {
        val list = mutableListOf<Any>()

        for (i in 0 until array.size) {
            val value = array[i]

            when (value) {
                is JSONObject -> list.add(jsonObjectToMap(value))
                is JSONArray -> list.add(jsonArrayToList(value))
                else -> list.add(value as Any) // 处理 null 值
            }
        }

        return list
    }
    // 构建标准响应结果
    private fun buildResult(code: Int, message: String, data: Any? = null): JSONObject {
        val result = JSONObject()
        result["code"] = code
        result["message"] = message

        // 添加data字段（如果不为null）
        if (data != null) {
            result["data"] = data
        }

        return result
    }
    // 错误事件
    private fun fireErrorEvent(errorCode: Int, errorMsg: String) {
        val data =JSONObject();
        data.put("errorCode", errorCode)
        data.put("errorMsg", errorMsg)
        fireGlobalEventCallback("error", data)
    }
    // 优化后的事件注册方法
    @UniJSMethod(uiThread = true)
    fun on(eventName: String, callback: UniJSCallback) {
        eventListeners[eventName] = true
        eventCallbacks[eventName] = callback  // 保存回调函数
        Log.d("TCPPlugin", "注册事件: $eventName")
        callback.invoke(buildResult(200, "事件注册成功"))
    }

    // 优化后的事件移除方法
    @UniJSMethod(uiThread = true)
    fun off(eventName: String, callback: UniJSCallback) {
        if (eventCallbacks.remove(eventName) != null) {
            eventListeners.remove(eventName)
            Log.d("TCPPlugin", "移除事件: $eventName")
            callback.invoke(buildResult(200, "事件取消成功"))
        } else {
            callback.invoke(buildResult(404, "事件未注册"))
        }
    }


    // 模块销毁
//    @UniJSMethod(uiThread = true)
    @Override
    override fun destroy() {
        isModuleActive = false
        disconnect()
        eventListeners.clear()
        eventCallbacks.clear()
        Log.d("TCPPlugin", "模块已销毁")
    }

}